package org.testfire.agent;

import java.io.IOException;
import java.util.List;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.testfire.agent.runner.TestSetRunner;
import org.testfire.support.S;
import org.testfire.support.StringOutputStream;

/**
 * Created by IntelliJ IDEA.
 * User: granum
 * Date: Sep 10, 2007
 * Time: 1:40:23 AM
 */
public class AgentToServerComm
{

    public static final String ACTION_REGISTER = "register";

    public static final String ACTION_TESTSET_RESULT = "testset_result";

    public AgentToServerComm()
    {

    }

    public static void sendTestsetResponse( AgentProperties props, TestSetRunner runner )
    {
        PostMethod post = setupPost( props, ACTION_TESTSET_RESULT, true );
//        try
//        {
//            post.setParameter( "testset_name", runner.getTestsetName() );
//            post.setParameter( "testset_id", runner.getTestsetId() );
//            post.setParameter( "testsetResult_id", runner.getTestsetResultId() );
//
//            if ( runner.getError() != null )
//            {
//                post.setParameter( "errormessage", StringOutputStream.printException( runner.getError() ) );
//            }
//            else
//            {
//                Result result = runner.getResult();
//                String str = String.valueOf( result.getFailureCount() );
//                post.setParameter( "failurecount", str );
//
//                str = String.valueOf( result.getRunTime() );
//                post.setParameter( "runtime", str );
//
//                List<Failure> failures = result.getFailures();
//
//                for ( int i = 0; i < failures.size(); i++ )
//                {
//                    Failure f = failures.get( i );
//                    String key = "failure_" + i + "_";
//
//                    String desc = f.getDescription().getDisplayName();
//                    desc = desc == null ? "" : desc;
//
//                    String message = f.getMessage();
//                    message = message == null ? "" : message;
//
//                    String trace = f.getTrace();
//                    trace = trace == null ? "" : trace;
//
//                    String testHeader =  f.getTestHeader();
//                    testHeader = testHeader == null ? "" : testHeader;
//
//                    post.setParameter( key + "description", desc);
//
//                    post.setParameter( key + "message", message );
//                    post.setParameter( key + "trace", trace);
//                    post.setParameter( key + "header", testHeader);
//                }
//
//            }
//
//            HttpClient httpclient = new HttpClient();
//            int result = httpclient.executeMethod( post );
//            String body = post.getResponseBodyAsString();
//            if ( result == HttpStatus.SC_OK )
//            {
//                System.out.println("Server has accepted results for testset " + runner.getTestsetName());
//            }
//            else
//            {
//                handleErrorResponse( post, result, body);
//            }
//        }
//
//        catch ( IOException e )
//        {
//            e.printStackTrace();
//        }
//        finally
//        {
//             // Release current connection to the connection pool once you are done
//            post.releaseConnection();
//        }
    }

    public static void registerSelfWithServer( AgentProperties props )
        throws IOException
    {
        PostMethod post = setupPost( props, ACTION_REGISTER, false);
        post.setParameter( "name", props.agentName );
        post.setParameter( "description", props.description );
        post.setParameter( "allowNonUserTests", String.valueOf( props.allowNonUserTests ) );
        post.setParameter( "host", props.agentAddress );

        HttpClient httpclient = new HttpClient();
        try
        {

            int result = httpclient.executeMethod( post );
            String body = post.getResponseBodyAsString();
            if ( result == HttpStatus.SC_OK )
            {
                Header h = post.getResponseHeader( "agent_id" );
                props.id = Integer.parseInt( h.getValue() );
                props.writeOut();
                h = post.getResponseHeader( "message" );
                if ( h != null && !S.empty( h.getValue() ) )
                {
                    System.out.println( "Server message: " + h.getValue() );
                }
                h = post.getResponseHeader( "response" );
                if ( h != null && !S.empty( h.getValue() ) )
                {
                    System.out.println( "Server response: " + h.getValue() );
                }

            }
            else
            {
                handleErrorResponse( post, result, body);
            }
        }
        finally
        {
            // Release current connection to the connection pool once you are done
            post.releaseConnection();
        }

    }

    /**
     * Set up a Post method containing the username, password and correct URL to post to.
     * @param props -
     * @param action The ACTION_* constant representing what this post is for.
     * @return A prepared post method, ready to accept parameters.
     */
    public static PostMethod setupPost( AgentProperties props, String action, boolean useJSF )
    {
        String serverRequestPath;
        if(useJSF){
            serverRequestPath = props.serverAddress + "/app_support/agent/agentRequest.jsf?task=" + action + "";
        }
        else{
            serverRequestPath = props.serverAddress + "/" + action + ".agent";
        }
        PostMethod post = new PostMethod( serverRequestPath );
        if ( props.id != null )
        {
            post.setParameter( "id", props.id.toString() );
        }
        post.setParameter( "username", props.userName );
        post.setParameter( "password", props.password );
        System.out.println( "Setting up to post to: " + serverRequestPath );
        return post;
    }


    public static void handleErrorResponse(PostMethod post, int result, String body)
    {
         Header h = post.getResponseHeader( "response" );
            String r = h != null && h.getValue() != null ? h.getValue() : "";
            System.out.println( "Response error: status " + result );
            System.out.println( "Server response: " + r + "\n" + body );


            throw new RuntimeException( "Bad response" );
    }

}
